﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace sztuczna_inteligencja
{



    class Neuron
    {
        //test
        public float waga;
        public bool ukryty = false;
        public Neuron(Random r, bool ukryty = false)
        {
            float rnd;
            do
            {
                rnd = r.Next();
                // losowanie wag trwa dopĂłki waga nie jest unikalna.
            } while (sprawdzWage(rnd) == false);
            waga = rnd;
            this.ukryty = ukryty;
            Program.wagi[Program.wagi.Length - 1] = waga;
        }

        private bool sprawdzWage(float waga)
        {
            // tutaj zostaje sprawdzona caĹa tablica wag, konkretnie sprawdzane jest czy wylosowana w konstruktorze waga jest unikalna (tj, czy inny neuron nie posiada juĹź takiej wagi).
            foreach (float number in Program.wagi)
            {
                if (waga == number)
                {
                    return false;
                }
            }
            return true;
        }
        /**
         * PrawdopodobieĹstwo aktywacji.
         * neuronyUkryte - tablica neuronĂłw z warstwy ukrytej.
         * neuronyWidoczne - tablica neuronĂłw z warstwy widocznej.
         */
        private float activProbVisible(Neuron[] neuronyUkryte, Neuron[] neuronyWidoczne)
        {
            int h = neuronyUkryte.Length; // liczba neuronĂłw.
            int v = neuronyWidoczne.Length;
            float W = 0; // suma iloczynĂłw wag.
            for (int i = 0; i < h; i++)
            {
                for (int j = 0; j < v; j++)
                {
                    W = neuronyUkryte[h].waga * neuronyWidoczne[v].waga * h;
                }
            }
            return (v + W);
        }
        /**
         * To samo co funkcja activProblVisible, w pĂłĹşniejszym etapie moĹźna bÄdzie je scaliÄ i zrobiÄ przed return prosty warunek.
         */
        private float hiddenProbVisible(Neuron[] neuronyUkryte, Neuron[] neuronyWidoczne)
        {
            int h = neuronyUkryte.Length; // liczba neuronĂłw.
            int v = neuronyWidoczne.Length;
            float W = 0; // suma iloczynĂłw wag.
            for (int i = 0; i < h; i++)
            {
                for (int j = 0; j < v; j++)
                {
                    W = neuronyUkryte[h].waga * neuronyWidoczne[v].waga * h;
                }
            }
            return (h + W);
        }
    }


    class Program
    {
        static float sigmod(float v)
        {
            return (float)(1 / (1 + Math.Exp(-v)));
        }

        static public float[] wagi;
        static void Main(string[] args)
        {
            int dlugoscWarstwy = 10;
            int iloscWarstw = 5;
            int liczba_neuronow = (dlugoscWarstwy * 2) * iloscWarstw;

            Random r = new Random();

            wagi = new float[liczba_neuronow];

            List<Neuron[,]> siec = new List<Neuron[,]>();

            for (int i = 0; i < iloscWarstw; i++)
            {
                Neuron[,] warstwa = new Neuron[dlugoscWarstwy, 2];
                for (int j = 0; j < dlugoscWarstwy; j++)
                {
                    warstwa[j, 0] = new Neuron(r); // tworze normalny neuron;
                    warstwa[j, 1] = new Neuron(r, true); // tworze ukryty neuron;
                }
                siec.Add(warstwa);
            }

            for (int i = 0; i < iloscWarstw; i++)
            {
                Console.WriteLine("==== Warstwa {0} ====", i);
                Console.WriteLine("Wagi widocznych neuronow: ");
                for (int j = 0; j < dlugoscWarstwy; j++)
                {
                    Console.Write(" {0}", siec[i][j, 0].waga);
                }
                Console.WriteLine();
                Console.WriteLine("Wagi ukrytych neuronow: ");
                for (int j = 0; j < dlugoscWarstwy; j++)
                {
                    Console.Write("{0}, ", siec[i][j, 1].waga);
                }
                Console.WriteLine();
                Console.WriteLine();
            }
        }
    }
}